package org.jeecg.modules.online.desform.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.online.desform.constant.WidgetTypes;
import org.jeecg.modules.online.desform.entity.DesignForm;
import org.jeecg.modules.online.desform.entity.DesignFormData;
import org.jeecg.modules.online.desform.service.IDesignFormDataService;
import org.jeecg.modules.online.desform.service.IDesignFormService;
import org.jeecg.modules.online.desform.service.IDesignFormToolsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * 表单设计器各种工具方法实现类
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2020-06-10
 */
@Service("designFormToolsServiceImpl")
public class DesignFormToolsServiceImpl implements IDesignFormToolsService {

    @Autowired
    ISysBaseAPI sysBaseAPI;

    @Autowired
    private IDesignFormDataService dataService;
    @Autowired
    private IDesignFormService designFormService;

    @Override
    public Result indexChangeModel(String desformCode, String oldKey, String newKey) {
        return this.commonIndexAction(desformCode, data -> {
            // 首先判断是否包含 oldKey
            if (data.containsKey(oldKey) && !oldKey.equals(newKey)) {
                // 将oldKey的值填充到newKey
                data.put(newKey, data.get(oldKey));
                // 删除oldKey
                data.remove(oldKey);
                return true;
            }
            return false;
        });
    }

    @Override
    public Result indexFormatData(String desformCode, String widgetType, String action, String model) {
        return this.commonIndexAction(desformCode, data -> {
            // 首先判断是否包含要操作的model
            if (!data.containsKey(model)) {
                return false;
            }
            Object value = data.getString(model);
            if (value == null) {
                return false;
            }
            WidgetTypes type = WidgetTypes.getByValue(widgetType);
            // 不识别的类型
            if (type == null) {
                return false;
            }
            switch (type) {
                case INPUT:
                    return this.formatInput(data, value, action, model);
                case DATE:
                    return this.formatDate(data, value, action, model);
                default:
                    // 不支持操作的类型
                    return false;
            }
        });
    }

    /**
     * 处理 input 组件
     *
     * @param data
     * @param value
     * @param action
     * @param model
     * @return
     */
    private boolean formatInput(JSONObject data, Object value, String action, String model) {
        Object afterValue;
        // 判断执行操作
        switch (action) {
            // 将数值转为字符串
            case "num2str":
                afterValue = value.toString();
                break;
            // 将字符串转为数字
            case "str2num":
                try {
                    afterValue = Integer.parseInt(value.toString());
                    break;
                } catch (NumberFormatException e) {
                    // 数据中只要有一条数据不是数字，就抛出异常
                    throw new JeecgBootException("\"" + value + "\"不是数字，拒绝执行此操作，请修改完数据后重试！");
                }
            default:
                // 不识别的操作
                return false;
        }
        data.put(model, afterValue);
        return true;
    }

    /**
     * 处理 date 组件
     *
     * @param data
     * @param value
     * @param action
     * @param model
     * @return
     */
    private boolean formatDate(JSONObject data, Object value, String action, String model) {
        Date dateTime;
        Object afterValue;
        // yyyy-MM-dd
        SimpleDateFormat date_sdf = DateUtils.date_sdf.get();
        // yyyy-MM-dd HH:mm:ss
        SimpleDateFormat datetimeFormat = DateUtils.datetimeFormat.get();
        try {
            dateTime = date_sdf.parse(value.toString());
        } catch (ParseException ex) {
            try {
                dateTime = datetimeFormat.parse(value.toString());
            } catch (ParseException e) {
                throw new JeecgBootException("\"" + value + "\"不是日期，拒绝执行此操作，请修改完数据后重试！");
            }
        }
        // 判断执行操作
        switch (action) {
            // 去除时间部分
            case "remove_time":
                afterValue = date_sdf.format(dateTime);
                break;
            // 增加时间部分
            case "add_time":
                afterValue = datetimeFormat.format(dateTime);
                break;
            default:
                // 不识别的操作
                return false;
        }
        data.put(model, afterValue);
        return true;
    }

    /**
     * 通用索引操作
     *
     * @param desformCode
     * @param function
     * @return
     */
    public Result commonIndexAction(String desformCode, Function<JSONObject, Boolean> function) {
        DesignForm designForm = designFormService.getByCode(desformCode);
        if (designForm == null) {
            return Result.error("不存在的表单");
        }
        // 封装 QueryWrapper
        LambdaQueryWrapper<DesignFormData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DesignFormData::getDesformCode, desformCode);
        // 根据 desformCode 查询出所有的数据
        List<DesignFormData> dataList = dataService.list(queryWrapper);
        List<DesignFormData> updateDataList = new ArrayList<>(dataList.size());
        // 遍历数据
        int count = 0;
        for (DesignFormData data : dataList) {
            JSONObject dataJSON = JSON.parseObject(data.getDesformDataJson());
            // （这里相当于js里的执行回调函数）
            boolean success;
            try {
                success = function.apply(dataJSON);
            } catch (JeecgBootException e) {
                return Result.error(e.getMessage());
            }
            if (success) {
                count++;
                // 更新对象
                DesignFormData updateData = new DesignFormData();
                updateData.setId(data.getId());
                updateData.setDesformDataJson(dataJSON.toJSONString());
                updateDataList.add(updateData);
            }
        }
        // 批量保存
        if (updateDataList.size() == 0) {
            return Result.ok("操作成功，但是没有任何更改");
        }
        if (dataService.updateBatchById(updateDataList)) {
            // 更新索引
            designFormService.redoAllIndexForce(designForm.getId(),null);
            if (count == dataList.size()) {
                return Result.ok(String.format("操作成功，%s条数据全部更改完毕", count));
            } else {
                return Result.ok(String.format("操作成功，更改了%s条数据，未更改%s条数据", count, dataList.size() - count));
            }
        } else {
            return Result.error("操作失败，原因未知…");
        }
    }

}
